﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Mimoza.CitrixPlugin
{
    public struct ResolutionMapping
    {
        public ResolutionMapping(Resolution res, int w, int h)
        {
            resolution = res;
            width = w;
            height = h;
        }

        public Resolution resolution;
        public int width;
        public int height;
    }

    public class CitrixFile
    {
        List<ResolutionMapping> mapping = new List<ResolutionMapping>();

        public CitrixFile()
        {
            AddMapRecord(Resolution.Res640x480, 640, 480);
            AddMapRecord(Resolution.Res800x600, 800, 600);
            AddMapRecord(Resolution.Res1024x768, 1024, 768);
            AddMapRecord(Resolution.Res1280x800, 1280, 800);
            AddMapRecord(Resolution.Res1280x720, 1280, 720);
            AddMapRecord(Resolution.Res1280x768, 1280, 768);
            AddMapRecord(Resolution.ResFullScreen, 800, 600);
        }

        public void CreateFile(string fullFileName, CitrixData data, Guid policyId)
        {
            string fileText = FillTemplate(data, policyId);

            Directory.CreateDirectory(Path.GetDirectoryName(fullFileName));

            if (IsOldRdpVersion)
            {
                using (FileStream writer = File.Create(fullFileName))
                {
                    byte[] buff = Encoding.Unicode.GetBytes(fileText);
                    writer.WriteByte(0xFF);
                    writer.WriteByte(0xFE);
                    writer.Write(buff, 0, buff.Length);
                }
            }
            else
            {
                using (StreamWriter writer = File.CreateText(fullFileName))
                {
                    writer.Write(fileText);
                    writer.Flush();
                }
            }
        }

        private bool IsOldRdpVersion
        {
            get { return m_bIsOldRdpVersion; }
            set { m_bIsOldRdpVersion = value; }
        }

        private string FillTemplate(CitrixData data, Guid policyId)
        {
            string text = Resource.ICAFileTemplate;
            string appOrServerName = string.IsNullOrEmpty(data.PublishedAppName) ? "Server" :
                data.PublishedAppName;

            text = text.Replace("%COMP%", data.Computer);
            text = text.Replace("%APPORSERVERNAME%", appOrServerName);

            ResolutionMapping mapping = FindResolutionMapping(data.Resolution);

            text = text.Replace("%WIDTH%", mapping.width.ToString());
            text = text.Replace("%HEIGHT%", mapping.height.ToString());

            text = text.Replace("%SCREENMODE%", GetYesNo(data.Resolution == Resolution.ResFullScreen));

            text = text.Replace("%USERNAME%", data.UserName);
            text = text.Replace("%USERDOMAIN%", data.UserDomain);

            int colorNum = (int)data.NumberColors;
            text = text.Replace("%DESIREDCOLOR%", colorNum.ToString());

            text = text.Replace("%CLIENTAUDIO%", GetOnOff(data.Sound.IsSoundEnabled));

            int audioBand = (int)data.Sound.SoundQuality;
            text = text.Replace("%AUDIOBAND%", audioBand.ToString());

            text = text.Replace("%INITPROGRAM%", 
                data.StartProgram.IsStartEnabled?data.StartProgram.ProgramPath:"");
            text = text.Replace("%INITPROGRAMDIR%",
                data.StartProgram.IsStartEnabled ? data.StartProgram.ProgramFolder : "");

            text = text.Replace("%POLICYID%", policyId.ToString());

            int val = data.IsStartOnStartup ? 1 : 0;
            text = text.Replace("%STARTUPFLAG%", val.ToString() );

            return text;
        }

        private string GetYesNo(bool value)
        {
            if (value) return "Yes";
            else return "No";
        }

        private string GetOnOff(bool value)
        {
            if (value) return "On";
            else return "Off";
        }

        private void AddMapRecord(Resolution res, int w, int h)
        {
            mapping.Add(new ResolutionMapping(res, w, h));
        }

        private ResolutionMapping FindResolutionMapping(Resolution res)
        {
            int index = mapping.FindIndex(r => r.resolution == res);
            if (index<0)
            {
                Common.Logger.Log.Error("RdpFile.CreateFile Error occured: type of resolution (" + 
                    res.ToString() + ") in not defined.");
                throw new ArgumentException();
            }

            return mapping[index];
        }

        private int GetKeyboradHookVal(Keyboard keyboard)
        {
            return (int)keyboard;
        }

        bool m_bIsOldRdpVersion = false; // Rdp 5
    }
}
